/* binary.cpp
Michael Zahniser, 12/12/09

Function definitions for the binary operators.
*/

#include "Operators.h"

using std::string;


namespace {
	string And = "and &";
	static const Do<And> binary_and;

	string LogicalAnd = "&&";
	static const Do<LogicalAnd> logical_and;

	string Or = "or |";
	static const Do<Or> binary_or;

	string LogicalOr = "||";
	static const Do<LogicalOr> logical_or;

	string Xor = "xor ^";
	static const Do<Xor> binary_xor;

	string LogicalXor = "^^";
	static const Do<LogicalXor> logical_xor;

	string Complement = "complement ~";
	static const Do<Complement> complement;

	string Not = "not";
	static const Do<Not> logical_not;

	string Right = "right >>";
	static const Do<Right> right;

	string Left = "left <<";
	static const Do<Left> left;
}



template <> void Do<And>::operator()(State &state) const
{
	state.Push(state.PopInt() & state.PopInt());
}



template <> void Do<LogicalAnd>::operator()(State &state) const
{
	state.Push(state.PopInt() && state.PopInt());
}



template <> void Do<Or>::operator()(State &state) const
{
	state.Push(state.PopInt() | state.PopInt());
}



template <> void Do<LogicalOr>::operator()(State &state) const
{
	state.Push(state.PopInt() || state.PopInt());
}



template <> void Do<Xor>::operator()(State &state) const
{
	state.Push(state.PopInt() ^ state.PopInt());
}



template <> void Do<LogicalXor>::operator()(State &state) const
{
	state.Push(!state.Pop() != !state.Pop());
}



template <> void Do<Complement>::operator()(State &state) const
{
	state.Push(~state.PopInt());
}



template <> void Do<Not>::operator()(State &state) const
{
	state.Push(!state.Pop());
}



template <> void Do<Right>::operator()(State &state) const
{
	long long b = state.PopInt();
	state.Push(state.PopInt() >> b);
}



template <> void Do<Left>::operator()(State &state) const
{
	long long b = state.PopInt();
	state.Push(state.PopInt() << b);
}
